﻿/****************************** Module Header ******************************\
Module Name:    MessageTemplate.cs
Project:        SQL Server Error Log Parsing module

Instances of this class represent the templates for SQL Server system 
messages and are used for parsing the entries in a SQL Server error log file.

This source is subject to the Microsoft Public License.
See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
All other rights reserved.

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace SQLServerSleuth.PowerShell.Commands.ParseERRORLOG
{
    /// <summary>
    /// Instances of this class represent the templates for SQL Server 
    /// system messages.
    /// </summary>
    public class MessageTemplate
    {
        /// <summary>
        /// The solitary constructor for the class assigns the given values 
        /// to the private fields.
        /// </summary>
        /// <param name="MessageID">The ID of the SQL Server system message.</param>
        /// <param name="Severity">The typical severity of system messages 
        /// of this type.</param>
        /// <param name="TokenCount">The number of replaceable tokens that 
        /// are present in the message template.</param>
        /// <param name="MessageTemplatePattern">A Regular Expression 
        /// pattern that corresponds to the system message's template.</param>
        public MessageTemplate
        (
            int MessageID,
            byte Severity,
            byte TokenCount,
            string MessageTemplatePattern
        )
        {
            this.MessageID = MessageID;
            this.Severity = Severity;
            this.TokenCount = TokenCount;

            //  Validate the user-supplied Regular Expression token.  I 
            //  expect that Regular Expressions are vulnerable to malicious 
            //  injection (as SQL code is), so I need a way to sanitize the 
            //  pattern supplied to the user (via the message templates 
            //  file).  This will require additional research, so in the 
            //  mean time, I am simply verifying that the pattern doesn't 
            //  exceed the width of its source (the [text] column of the 
            //  [sys].[messages] catalog view).
            if (2048 >= MessageTemplatePattern.Length)
            {
                //  Instantiate the Regular Expression object using the same 
                //  properties for each instance of this class.
                this._regularExpression = new Regex(
                    MessageTemplatePattern,
                    MessageTemplate.regexOptions
                );
            }
            else
            {
                throw new System.ArgumentException
                (
                    "The message template pattern exceeds the maximum length.",
                    "MessageTemplatePattern"
                );
            }

            return;
        }

        /// <summary>
        /// See the corresponding parameter of the <see cref="MessageTemplate"/> constructor.
        /// </summary>
        public int MessageID
        {
            get
            {
                return this._messageID;
            }

            set
            {
                this._messageID = value;
            }
        }
        private int _messageID;

        /// <summary>
        /// A Regular Expression object that is used to match the text of 
        /// entries in the SQL Server error log that correspond to the given 
        /// message ID value.
        /// </summary>
        public Regex RegularExpression
        {
            get
            {
                return this._regularExpression;
            }
        }
        private Regex _regularExpression;

        /// <summary>
        /// See the corresponding parameter of the <see cref="MessageTemplate"/> constructor.
        /// </summary>
        public byte Severity
        {
            get
            {
                return this._severity;
            }

            set
            {
                this._severity = value;
            }
        }
        private byte _severity;

        /// <summary>
        /// See the corresponding parameter of the <see cref="MessageTemplate"/> constructor.
        /// </summary>
        public byte TokenCount
        {
            get
            {
                return this._tokenCount;
            }

            set
            {
                this._tokenCount = value;
            }
        }
        private byte _tokenCount;

        /// <summary>
        /// A constant used to instantiate the Regular Expression property.
        /// </summary>
        private static readonly RegexOptions regexOptions = RegexOptions.IgnoreCase | RegexOptions.Singleline;
    }
}
